package ejbSessions;

import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.ejb.Stateless;
import javax.persistence.*;

import org.jboss.beans.metadata.api.annotations.Create;

import EJBPackage.*;

@Stateless
public class ManagerAbilita implements ManagerAbilitaRemote, ManagerAbilitaLocal {
	@PersistenceContext(unitName = "SWIMv2")
	EntityManager database;

	public ManagerAbilita() {
	}

	public void addAbilita(String nome, String descrizione){
		Abilita abilita= new Abilita();
		abilita.setNome(nome);
		abilita.setDescrizione(descrizione);

		try {
			Query cercaAbilita = database.createQuery("FROM Abilita a WHERE a.nome=:nome");
			cercaAbilita.setParameter("nome", nome);
			Abilita a = (Abilita) cercaAbilita.getSingleResult();
		}catch(Exception e) {
			database.persist(abilita);
		}
	}

	public void addNotifica(int idUtente,String tipo, int scelta, int idRichiesta){

		Notifica nuova= new Notifica();
		nuova.setTipoNotifica(tipo);
		database.persist(nuova);
		
		try{
			Query cercaUtente = database.createQuery("FROM Utente u WHERE u.id=:idUtente");
			cercaUtente.setParameter("idUtente", idUtente);
			Query cercaRichiesta = database.createQuery("FROM RichiestaAbilita a WHERE a.id=:idRichiesta");
			cercaRichiesta.setParameter("idRichiesta", idRichiesta);
			Utente u = (Utente) cercaUtente.getSingleResult();
			RichiestaAbilita richiesta = (RichiestaAbilita) cercaRichiesta.getSingleResult();
			u.getNotifica().add(nuova);
			if(Costanti.AGGIUNTA==scelta){
				Abilita abilita = new Abilita();
				abilita.setNome(richiesta.getNome());
				abilita.setDescrizione(richiesta.getDescrizione());
				database.persist(abilita);
			}
			database.remove(richiesta);
			database.flush();
		}catch (Exception e) {
			e.printStackTrace();
		}
		
	}

	public void deleteAbilita(String nome){

		try {
			Query q = database.createQuery("FROM Abilita a WHERE a.nome=:nome");
			q.setParameter("nome",nome);
			Abilita abilita = (Abilita) q.getSingleResult();
			Set<Utente> listaUtenti = abilita.getUtenti();
			Iterator<Utente> iUtenti = listaUtenti.iterator();
			while(iUtenti.hasNext()){
				Utente u=iUtenti.next();
				Set<Abilita> listaAbilita = u.getAbilita();
				Iterator<Abilita> iAbilita = listaAbilita.iterator();
				while(iAbilita.hasNext()){
					Abilita a = iAbilita.next();
					if(a.getId()==abilita.getId()){
						u.getAbilita().remove(a);
						break;
					}
				}
			}
			Set<RichiestaAiuto> listaRichieste = abilita.getRichieste();
			Iterator<RichiestaAiuto> iAiuto = listaRichieste.iterator();
			while(iAiuto.hasNext()){
				RichiestaAiuto richiesta = iAiuto.next();
				Set<Abilita> listaAbilita = richiesta.getAbilita();
				Iterator<Abilita> iAbilita = listaAbilita.iterator();
				while(iAbilita.hasNext()){
					Abilita a = iAbilita.next();
					if(a.getId()==abilita.getId()){
						richiesta.getAbilita().remove(a);
						break;
					}
				}
			}
			database.flush();
			database.remove(abilita);
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	public void aggiuntaAbilitaUtente(int idUtente,String nomeAbilita){

		try {
			Query qu = database.createQuery("FROM Utente u WHERE u.id=:id");
			qu.setParameter("id",idUtente);
			Query qa = database.createQuery("FROM Abilita a WHERE a.nome=:nome");
			qa.setParameter("nome",nomeAbilita);
			((Utente) qu.getSingleResult()).getAbilita().add((Abilita) qa.getSingleResult());
			database.flush();
		} catch (EntityNotFoundException exc) { 
		} catch (javax.persistence.NoResultException exc) { 
		} catch (NonUniqueResultException exc) {
		}

	}

	public void deleteAbilitaUtente(int idUtente,String nomeAbilita){

		try {
			Query qu = database.createQuery("FROM Utente u WHERE u.id=:id");
			qu.setParameter("id",idUtente);
			Query qa = database.createQuery("FROM Abilita a WHERE a.nome=:nome");
			qa.setParameter("nome",nomeAbilita);
			((Utente) qu.getSingleResult()).getAbilita().remove((Abilita) qa.getSingleResult());
			database.flush();
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	public void aggiuntaRichiestaAbilitaUtente(int idUtente,String nomeRichiestaAbilita){

		try {
			Query qu = database.createQuery("FROM Utente u WHERE u.id=:id");
			qu.setParameter("id",idUtente);
			Query qa = database.createQuery("FROM RichiestaAbilita rab WHERE rab.nome=:nome");
			qa.setParameter("nome",nomeRichiestaAbilita);
			((Utente) qu.getSingleResult()).getRichiesteAbilita().add((RichiestaAbilita) qa.getSingleResult());
			database.flush();
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	public void deleteRichiestaAbilitaUtente(int idRichiesta){

		try {
			Query qa = database.createQuery("FROM RichiestaAbilita rab WHERE rab.id=:idRichiesta");
			qa.setParameter("idRichiesta",idRichiesta);
			RichiestaAbilita richiesta = (RichiestaAbilita)qa.getSingleResult();
			database.remove(richiesta);
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	public void nuovaRichiestaAbilitaUtente(int idUtente,String nome,String descrizione){

		RichiestaAbilita aggiunta= new RichiestaAbilita();
		//    		aggiunta.generateId();
		aggiunta.setNome(nome);
		aggiunta.setDescrizione(descrizione);

		try {
			if(database.find(RichiestaAbilita.class, aggiunta.getId()) == null) {
				database.persist(aggiunta);
			}
		}catch(NoResultException e) {
			database.persist(aggiunta);
		}

		aggiuntaRichiestaAbilitaUtente(idUtente,nome);

	}
	
	public List<RichiestaAbilita> getTutteRichieste(){
		List<RichiestaAbilita> richieste = null;
		try {
			Query qa = database.createQuery("FROM RichiestaAbilita rab");
			richieste = (List<RichiestaAbilita>)qa.getResultList();
		}catch (Exception e) {
			e.printStackTrace();
		}
		
		return richieste;
	}
	
	public RichiestaAbilita getRichiesta(int idRichiesta){
		RichiestaAbilita richiesta = null;
		try {
			Query qa = database.createQuery("FROM RichiestaAbilita rab WHERE rab.id=:id");
			qa.setParameter("id",idRichiesta);
			richiesta = (RichiestaAbilita) qa.getSingleResult();
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return richiesta;
	}
	
	@Override
	public List<Abilita> getTutteAbilita() {
		List<Abilita> abilita = null;
		try{
			Query tutteAbilita = database.createQuery("FROM Abilita a");
			abilita = (List<Abilita>)tutteAbilita.getResultList();
		} catch (Exception e) { 
			e.printStackTrace();
		}
		return abilita;
	}

	@Override
	public Abilita getAbilita(int idAbilita) {
		
		try{
			Query abilita = database.createQuery("FROM Abilita a WHERE a.id=:idAbilita");
			abilita.setParameter("idAbilita", idAbilita);
			return (Abilita) abilita.getSingleResult();
		}catch (Exception e) {
			e.printStackTrace();
		}
		
		return null;
	}

	@Override
	public void aggiuntaAbilitaUtente(int idUtente, int idAbilita) {
		try {
			Query qu = database.createQuery("FROM Utente u WHERE u.id=:id");
			qu.setParameter("id",idUtente);
			Query qa = database.createQuery("FROM Abilita a WHERE a.id=:nome");
			qa.setParameter("nome",idAbilita);
			((Utente) qu.getSingleResult()).getAbilita().add((Abilita) qa.getSingleResult());
			database.flush();
		}catch (Exception e) {
			e.printStackTrace();
		}	
	}
	
	public void modificaAbilita(int idAbilita, String nome, String descrizione){

		Abilita abilita;
		
		try {
			Query qa = database.createQuery("FROM Abilita a WHERE a.id=:id");
			qa.setParameter("id",idAbilita);
			abilita = (Abilita) qa.getSingleResult();
			abilita.setNome(nome);
			abilita.setDescrizione(descrizione);
			database.flush();
		} catch (EntityNotFoundException exc) { 
		} catch (javax.persistence.NoResultException exc) { 
		} catch (NonUniqueResultException exc) {
		}		

	}

	@Override
	public void deleteNotifica(int idNotifica) {
		try{
			Query cercaNotifica = database.createQuery("FROM Notifica n WHERE n.id=:idNotifica");
			cercaNotifica.setParameter("idNotifica", idNotifica);
			Notifica notifica = (Notifica) cercaNotifica.getSingleResult();
			database.remove(notifica);
		}catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Override
	public Notifica getNotifica(int idNotifica) {
		Notifica notifica = null;
		try{
			Query cercaNotifica = database.createQuery("FROM Notifica n WHERE n.id=:idNotifica");
			cercaNotifica.setParameter("idNotifica", idNotifica);
			notifica = (Notifica) cercaNotifica.getSingleResult();
		}catch (Exception e) {
			e.printStackTrace();
		}
		return notifica;
	}


}
